package com.feng.thread.concurrent;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
	private static final int N = 10;

	public static void main(String[] args) throws InterruptedException {
		CountDownLatch doneSignal = new CountDownLatch(N);
		CountDownLatch startSignal = new CountDownLatch(1);// 开始执行信号，计数为1，用作一个简单的开关

		for (int i = 1; i <= N; i++) {
			new Thread(new Worker(i, doneSignal, startSignal)).start();// 线程启动了
		}
		System.out.println("begin------------");
		// dosomething()线程开始前可以做一些事情
		startSignal.countDown();// 开始执行啦
		doneSignal.await();// 等待所有的线程执行完毕,当countDown（）计数为0时放行
		// System.err.println(doneSignal.getCount());//0
		// dosomething()所有线程执行完后可以做其他的
		System.out.println("Ok");

	}

	// 线程类
	static class Worker implements Runnable {
		private final CountDownLatch doneSignal;
		private final CountDownLatch startSignal;
		private int beginIndex;

		// 有参构造方法
		Worker(int beginIndex, CountDownLatch doneSignal, CountDownLatch startSignal) {
			this.startSignal = startSignal;
			this.beginIndex = beginIndex;
			this.doneSignal = doneSignal;
		}

		@Override
		public void run() {
			try {
				startSignal.await(); // 等待开始执行信号的发布，所有线程都在此等待
				beginIndex = (beginIndex - 1) * 10 + 1;
				for (int i = beginIndex; i < beginIndex + 10; i++) {// 10个线程，每个线程10个数
					System.out.println(Thread.currentThread().getName() + "-----" + i);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				// 用N初始化的 CountDownLatch 可以使一个线程在N个线程完成某项操作之前一直等待，或者使其在某项操作完成 N
				// 次之前一直等待。
				System.err.println(doneSignal.getCount());// 1,2,3,...,1,0
				doneSignal.countDown();// finally里放最终会执行的代码
			}
		}
	}
}
